home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / ded / Scandir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1984-04-25  |  2.5 KB  |  97 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#)scandir.c    4.2 (Berkeley) 7/1/83";
  3. static char RCSid[] =
  4. "$Header: Scandir.c,v 1.4 84/04/24 22:53:33 lepreau Exp $";
  5. #endif
  6.  
  7. /*
  8.  * Hacked up version for ded.  Called Scandir() now, note cap.
  9.  * Returns -1 if can't read dir, -2 if out of memory.
  10.  */
  11.  
  12. /*
  13.  * Scan the directory dirname calling select to make a list of selected
  14.  * directory entries then sort using qsort and compare routine dcomp.
  15.  * Returns the number of entries and a pointer to a list of pointers to
  16.  * struct direct (through namelist). Returns -1 if there were any errors.
  17.  */
  18.  
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #ifdef BSD42
  22. # include <sys/dir.h>
  23. # define MINSIZE 12
  24. # define ESTSIZE 24
  25. #else
  26. # include <dir.h>        /* will be ndir.h on some systems */
  27. # define MINSIZE 16        /* min length of a dir entry with inode # */
  28. # define ESTSIZE 20        /* take into acct dir usually not full */
  29. #endif
  30. #include <stdio.h>
  31.  
  32. #include "ded.h"
  33.  
  34. /*VARARGS3*/ /* Only way to get lint to shut up about 4th arg == 0 in ded.c */
  35. Scandir(dirname, namelist, select, dcomp)
  36.     char *dirname;
  37.     struct lbuf **namelist;
  38.     int (*select)(), (*dcomp)();
  39. {
  40.     register struct direct *d;
  41.     char *p;
  42.     register struct lbuf *names;
  43.     register int nitems;
  44.     struct stat stb;
  45.     long arraysz;
  46.     DIR *dirp;
  47.  
  48.     if ((dirp = opendir(dirname)) == NULL)
  49.         return(-1);
  50.     if (fstat(dirp->dd_fd, &stb) < 0)
  51.         return(-1);
  52.  
  53.     /*
  54.      * estimate the array size by taking the size of the directory file
  55.      * and dividing it by a multiple of the minimum size entry. 
  56.      */
  57.     arraysz = (stb.st_size / ESTSIZE);
  58.     names = ALLOC(struct lbuf, arraysz);
  59.     if (names == NULL)
  60.         return(-2);
  61.  
  62.     nitems = 0;
  63.     while ((d = readdir(dirp)) != NULL) {
  64.         if (select != NULL && !(*select)(d))
  65.             continue;    /* just selected names */
  66.         /*
  67.          * Make a minimum size copy of the data
  68.          */
  69.         p = ALLOC(char, d->d_namlen+1);
  70.         if (p == NULL)
  71.             return(-2);
  72.         /*
  73.          * Check to make sure the array has space left and
  74.          * realloc the maximum size.
  75.          */
  76.         if (++nitems >= arraysz) {
  77.             if (fstat(dirp->dd_fd, &stb) < 0)
  78.                 return(-1);    /* just might have grown */
  79.             arraysz = stb.st_size/MINSIZE;
  80.             names = RALLOC(struct lbuf, names, arraysz);
  81.             if (names == NULL)
  82.                 return(-2);
  83.         }
  84.         names[nitems-1].lino = d->d_ino;
  85.         names[nitems-1].namlen = d->d_namlen;
  86.         bcopy(d->d_name, p, d->d_namlen+1);
  87.         names[nitems-1].namep = p;
  88.         if (nitems % 10 == 0)
  89.               (void) putchar('.');
  90.     }  
  91.     closedir(dirp);
  92.     if (nitems && dcomp != NULL)
  93.         qsort((char *)names, nitems, sizeof(struct lbuf), dcomp);
  94.     *namelist = names;
  95.     return(nitems);
  96. }
  97.